package com.winit.openapi.mms.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.spi.SPIException;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.BpartnerService;
import com.winit.erp.spi.bpartner.command.BpartnerCommand;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.mms.spi.v2.finance.FinanceGoodsService;
import com.winit.mms.spi.v2.finance.command.CheakFinanceGoodsCommand;
import com.winit.mms.spi.v2.finance.command.FinanceGoodsListCommand;
import com.winit.mms.spi.v2.finance.command.HSCodeCommand;
import com.winit.mms.spi.v2.finance.command.ModifyFinanceApplyCommand;
import com.winit.mms.spi.v2.finance.command.QueryFinanceGoodsCommand;
import com.winit.mms.spi.v2.finance.command.QueryFinanceGoodsDetalCommand;
import com.winit.mms.spi.v2.finance.command.QueryFinanceSupplierCommand;
import com.winit.mms.spi.v2.finance.command.QueryFinanceSupplierTaxPicCommand;
import com.winit.mms.spi.v2.finance.command.QueryWYTGoodsCommand;
import com.winit.mms.spi.v2.finance.command.QueryWYTGoodsDetailCommand;
import com.winit.mms.spi.v2.finance.command.SaveFinanceGoodsCommand;
import com.winit.mms.spi.v2.finance.vo.FinanceGoodsCheckRetrunVo;
import com.winit.mms.spi.v2.finance.vo.FinanceGoodsDetailVo;
import com.winit.mms.spi.v2.finance.vo.FinanceGoodsVo;
import com.winit.mms.spi.v2.finance.vo.FinanceSupplierVo;
import com.winit.mms.spi.v2.finance.vo.GoodsHSDetailVo;
import com.winit.mms.spi.v2.finance.vo.WYTGoodsVo;
import com.winit.mms.spi.v2.item.vo.PageVo;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.FastJSONUtils;
import com.winit.openapi.util.ValidateUtil;
import com.winit.ums.spi.UmsCustomerService;
import com.winit.ums.spi.commnad.customer.QueryCompanylCommand;
import com.winit.ums.spi.finance.FinanceUserService;
import com.winit.ums.spi.finance.command.QueryFinanceCommand;
import com.winit.ums.spi.finance.vo.FinanceBaseInfoVo;
import com.winit.ums.spi.vo.CustomerInfoVO;

/**
 * 金融商品OpenAPI接口部分
 * 
 * @version
 * 
 * <pre>
 * Author	Version		Date		Changes
 * sheng.huang 	1.0  		2016年7月20日 	Created
 * </pre>
 * 
 * @since 1.
 */
@Controller
@RequestMapping(value = "/mms/finance/goods")
public class FinanceGoodsController extends BaseController {

    @Resource
    private FinanceGoodsService financeGoodsService;

    @Resource
    private BpartnerService     bpartnerService;
    @Resource
    private UmsCustomerService  umsCustomerService;
    @Resource
    private FinanceUserService  financeUserService;

    /**
     * 检测金融商品
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/check")
    public String checkGoods(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 校验参数
        validateParams(requestMsg.getData(), "goodsCode",60, "商品编码");
        CheakFinanceGoodsCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(),
            CheakFinanceGoodsCommand.class);
        command.setFinanceCustomerCode(getFinanceCustomerCode());// 金选客户编码
        String wylCustomerCode = getWYLCustomerCode();
        command.setWylCustomerCode(wylCustomerCode);// 万邑联客户编码
        command.setIsbindingWYL(wylCustomerCode == null ? false : true);// 是否绑定万邑联帐号
        command.setCtx(CommandContext.getContext());
        FinanceGoodsCheckRetrunVo vo = financeGoodsService.cheakFinanceGoods(command);
        responseMsg.setData(vo);
        return SUCCESS;
    }

    /**
     * 保存金融商品
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/save")
    public String saveGoods(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        validateParam(requestMsg.getData());
        SaveFinanceGoodsCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(),
            SaveFinanceGoodsCommand.class);
        command.setCustomerCode(getFinanceCustomerCode());
        command.setCtx(CommandContext.getContext());
        Integer returnValue =0;

        try{
            returnValue = financeGoodsService.saveFinanceGoods(command);
        }catch(SPIException e){
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
        }
        responseMsg.setData(returnValue);
        return SUCCESS;
    }

    /**
     * 供应商列表查询查询接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/querySupplier")
    public String querySupplierList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryFinanceSupplierCommand command = new QueryFinanceSupplierCommand();
        command.setCustomerCode(getFinanceCustomerCode());
        command.setCtx(CommandContext.getContext());
        List<FinanceSupplierVo> voList = financeGoodsService.getFinanceSupplierList(command);
        responseMsg.setData(voList);
        return SUCCESS;
    }

    /**
     * 根据供应商ID查询供应商查询发票接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/querydetailPicBySuppliedId")
    public String querydetailPicBySuppliedId(@ModelAttribute RequestMsg requestMsg,
                                             @ModelAttribute ResponseMsg responseMsg) {
        validateParams(requestMsg.getData(), "suppliedId",20, "供应商编码");
        QueryFinanceSupplierTaxPicCommand taxCommand = FastJSONUtils.toJavaObject(requestMsg.getData(),
            QueryFinanceSupplierTaxPicCommand.class);
        taxCommand.setCtx(CommandContext.getContext());
        List<String> picList = financeGoodsService.getFinanceSupplierTaxPicList(taxCommand);
        responseMsg.setData(picList);
        return SUCCESS;
    }

    /**
     * 根据输入的HSCode查询退税费率接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryHSCode")
    public String queryHSCode(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        validateParams(requestMsg.getData(), "hsCode",128, "税则编码");
        HSCodeCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(), HSCodeCommand.class);
        command.setCtx(CommandContext.getContext());
        command.setCountryCode("CN");// 写死 只取中国的税则编码
        GoodsHSDetailVo vo = financeGoodsService.getGoodsHSDetailInfo(command);
        responseMsg.setData(vo);
        return SUCCESS;
    }
    /**
     * 新商品批量导入接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/batchInsert")
    public String batchInsertGoods(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        validateParam(requestMsg.getData(),"financeGoodsList");
        FinanceGoodsListCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(),
            FinanceGoodsListCommand.class);
        command.setCustomerCode(getFinanceCustomerCode());
        command.setCtx(CommandContext.getContext());
        Long returnValue = financeGoodsService.batchInsertFinanceGoods(command);
        responseMsg.setData(returnValue);
        return SUCCESS;
    }

    /**
     * 万邑联商品批量导入查询接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryWYLGoods")
    public String queryWYLGoods(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 没绑定万邑通帐号就需要提示绑定万邑通帐号
        if (StringUtils.isBlank(getWYLCustomerCode())) {
            throw new SPIException(ErrorCode.CUSTOMER_INFO_NOT_BONDING);
        }
        QueryWYTGoodsCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(), QueryWYTGoodsCommand.class);
        command.setFinanceCustomerCode(getFinanceCustomerCode());// 金选客户编码
        command.setWylCustomerCode(getWYLCustomerCode());// 万邑联客户编码
        PageVo pageVo = SetPageParams(requestMsg.getData());
        command.setPageVo(pageVo);
        command.setCtx(CommandContext.getContext());
        Page<WYTGoodsVo> pageVos = financeGoodsService.getWYTGoodsList(command);
        responseMsg.setData(pageVos);
        return SUCCESS;
    }

    /**
     * 万邑联商品批量导入查询接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/batchInsertWYLGoods")
    public String batchInsertWYLGoods(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryWYTGoodsDetailCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(),
            QueryWYTGoodsDetailCommand.class);
        command.setFinanceCustomerCode(getFinanceCustomerCode());// 金选客户编码
        command.setWylCustomerCode(getWYLCustomerCode());// 万邑联客户编码
        command.setCtx(CommandContext.getContext());
        String returnValue =financeGoodsService.getWYTGoodsDetailInsertFinance(command); 
        responseMsg.setData(returnValue);
        return SUCCESS;
    }

    /**
     * 商品列表查询接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryListByPage")
    public String queryGoodsListByPage(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryFinanceGoodsCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(),
            QueryFinanceGoodsCommand.class);
        command.setCustomerCode(getFinanceCustomerCode());
        command.setCtx(CommandContext.getContext());
        PageVo pageVo = SetPageParams(requestMsg.getData());
        command.setPageVo(pageVo);
        Page<FinanceGoodsVo> voList = financeGoodsService.queryFinanceGoodsListByPage(command);
        responseMsg.setData(voList);
        return SUCCESS;
    }

    /**
     * 万邑联商品批量导出接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryGoodsAsList")
    public String queryGoodsAsList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryFinanceGoodsCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(),
            QueryFinanceGoodsCommand.class);
        command.setCustomerCode(getFinanceCustomerCode());
        command.setCtx(CommandContext.getContext());
        List<FinanceGoodsDetailVo> voList = financeGoodsService.queryFinanceGoodsList(command);
        responseMsg.setData(voList);
        return SUCCESS;
    }

    /**
     * 商品详情查询接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryDetail")
    public String queryGoodsDetail(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 校验参数
        validateParams(requestMsg.getData(), "goodsCode",128, "商品编码");
        QueryFinanceGoodsDetalCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(),
            QueryFinanceGoodsDetalCommand.class);
        command.setCustomerCode(getFinanceCustomerCode());
        command.setCtx(CommandContext.getContext());
        FinanceGoodsDetailVo vo = financeGoodsService.queryFinanceGoodsDetal(command);
        responseMsg.setData(vo);
        return SUCCESS;
    }
    
    /**
     * 商品详情查询接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/submit")
    public String submitGoods(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 校验参数
        validateParams(requestMsg.getData(), "goodsCode",60, "商品编码");
        ModifyFinanceApplyCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(),
            ModifyFinanceApplyCommand.class);
        command.setCustomerCode(getFinanceCustomerCode());
        command.setCtx(CommandContext.getContext());
        Long returnCode = financeGoodsService.submitFinanceGoods(command);
        responseMsg.setData(returnCode);
        return SUCCESS;
    }
    
    /**
     * 商品详情查询接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/modify")
    public String modifyGoods(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 校验参数
        validateParams(requestMsg.getData(), "goodsCode",60, "商品编码");
        validateParams(requestMsg.getData(), "id",20, "商品主键");
        ModifyFinanceApplyCommand command = FastJSONUtils.toJavaObject(requestMsg.getData(),
            ModifyFinanceApplyCommand.class);
        command.setCustomerCode(getFinanceCustomerCode());
        command.setCtx(CommandContext.getContext());
        Long returnCode = financeGoodsService.modifyFinanceGoods(command);
        responseMsg.setData(returnCode);
        return SUCCESS;
    }
    /**
     * 根据上下文获取金融帐号的客户编码
     * 
     * @return
     */
    private String getFinanceCustomerCode() {
        String userId = CommandContext.getContext().getUserId();
        BpartnerCommand bpartnerCommand = new BpartnerCommand();
        bpartnerCommand.setcBpartnerId(Long.valueOf(userId));
        Bpartner bpartner = bpartnerService.queryBpartnerById(bpartnerCommand);
        if (bpartner == null) {
            throw new SPIException(ErrorCode.CUSTOMER_CODE_IS_NULL);
        }
        return bpartner.getValue();
    }

    /**
     * 根据上下文获取金融帐号的客户编码
     * 
     * @return
     */
    private String getWYLCustomerCode() {
        // 上下文拿到登录帐号
        CommandContext ctx = CommandContext.getContext();
        QueryFinanceCommand qcommand = new QueryFinanceCommand();
        qcommand.setCtx(ctx);
        qcommand.setUserName(ctx.getUsername());
        FinanceBaseInfoVo baseInfo = financeUserService.queryFinanceCustomer(qcommand);
        if (!StringUtils.isBlank(baseInfo.getWinitUserName())) {
            QueryCompanylCommand command = new QueryCompanylCommand();
            command.setCtx(ctx);
            command.setEmail(baseInfo.getWinitUserName());
            CustomerInfoVO infoVo = umsCustomerService.queryCompanyByUserName(command);
            return infoVo.getCode();
        }
        return null;
    }

    /**
     * 校验参数是否异常
     * 
     * @param params JSON参数
     * @param name 需要校验的KEY
     * @param cnMsg 返回的中文名称
     */
    private void validateParams(Object params, String name, Integer lenght,String cnMsg) {
        JSONObject json = JSON.parseObject(params.toString());
        if (json == null) {
            return;
        }
        ValidateUtil.validImportMaxLength(json, name, cnMsg, lenght, true);
        // 校验是否存在特殊字符
       /* if (json.getString(name) != null) {
            if (!json.getString(name).matches("[^@#￥$%&(){}<>]{0,}")) {
                throw new ApiException(ErrorCode.NOT_INPUT_SPECHARS, cnMsg);
            }
        }*/
    }
    
    private void validateParam(Object params,String split){
        JSONObject json = JSON.parseObject(params.toString());
        if (json == null) {
            return;
        }
        JSONArray result = json.getJSONArray(split);
        if(result!=null){
            for(int i=0;i<result.size();i++){
                validateParam(result.get(i));
            }
        }
    }
    /**
     * 校验长度
     * @param params
     */
    private void validateParam(Object params){
        // 校验参数
        JSONObject json = JSON.parseObject(params.toString());
        if (json == null) {
            return;
        }
        ValidateUtil.validBigDecimal(json, "onSellingSaleprice", "售卖价格",false);
        ValidateUtil.validImportMaxLength(json, "goodsCode", "商品编码", 60, true);
        ValidateUtil.validImportMaxLength(json, "suppliedId", "供应商编码", 20, true);
        ValidateUtil.validImportMaxLength(json, "goodsChineseName", "中文品名", 510, false);
        ValidateUtil.validImportMaxLength(json, "goodsEnglishName", "英文品名", 510, false);
        ValidateUtil.validImportMaxLength(json, "unit", "开票单位", 200, false);
        ValidateUtil.validImportMaxLength(json, "hsCode", "税则编码", 128, false);
        ValidateUtil.validImportMaxLength(json, "declareElement", "申报要素", 2000, false);
        ValidateUtil.validImportMaxLength(json, "declareName", "申报品名", 128, false);
        ValidateUtil.validImportMaxLength(json, "model", "型号", 510, false);
        ValidateUtil.validImportMaxLength(json, "barndName", "品牌名称", 510, false);
        ValidateUtil.validImportMaxLength(json, "saleWebsite", "售卖网址", 4000, false);
        ValidateUtil.validImportMaxLength(json, "onSellingSaleprice", "售卖价格", 16, false);
        ValidateUtil.validImportMaxLength(json, "setInstrucions", "成套说明", 510, false);
        
    }
    /**
     * 返回分页数据
     * 
     * @param pagelist
     * @return
     */
    public Map<String, Object> setPageData(Page<?> pagelist) {
        if (pagelist == null) {
            return null;
        }
        long total = pagelist.total;
        if (total < 1) {
            return null;
        }

        Map<String, Object> pageVo = new HashMap<String, Object>();
        pageVo.put("pageNo", pagelist.getPageable().getPageNumber());
        pageVo.put("pageSize", pagelist.getPageable().getPageSize());
        pageVo.put("totalCount", total);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("list", pagelist.content);
        data.put("pageVo", pageVo);
        return data;
    }

    /**
     * 设置分页参数
     * 
     * @param object
     * @return
     */
    public PageVo SetPageParams(Object object) {
        if (object == null) return null;
        if (object instanceof JSONObject) {
            JSONObject json = (JSONObject) object;
            if (json.containsKey("pageVo")) {
                Object obj = json.get("pageVo");
                if (obj instanceof JSONObject) {
                    return SetPageVo(obj);
                } else {
                    throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageVo");
                }
            }
        } else {
            throw new ApiException(ErrorCode.JSON_FORMAT_ERROR, "data");
        }
        return null;
    }

    private PageVo SetPageVo(Object obj) {
        PageVo pageVo = new PageVo();
        JSONObject pageParams = (JSONObject) obj;
        ValidateUtil.validInteger(pageParams, "pageNo");
        ValidateUtil.validInteger(pageParams, "pageSize");
        if (pageParams.containsKey("pageNo")) {
            int pageNo = pageParams.getInteger("pageNo");
            if (pageNo < 1) {
                throw new ApiException(ErrorCode.FIELD_ERROR, "pageNo");
            }
            pageVo.setPageNo(pageNo);
        }
        if (pageParams.containsKey("pageSize")) {
            int pageSize = pageParams.getInteger("pageSize");
            if (pageSize < 1) {
                throw new ApiException(ErrorCode.FIELD_ERROR, "pageSize");
            }
            pageVo.setPageSize(pageSize);
        }
        return pageVo;
    }
}
